package com.oa.admin.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.joneying.common.annotation.CommonService;
import com.joneying.common.web.response.Resp;
import com.oa.admin.dto.*;
import com.oa.admin.entity.CarApplication;
import com.oa.admin.entity.Insurance;
import com.oa.admin.entity.Maintain;
import com.oa.admin.exportvo.CarExportVO;
import com.oa.admin.mapper.CarApplicationMapper;
import com.oa.admin.mapper.MaintainMapper;
import com.oa.admin.service.ICarApplicationService;
import com.oa.admin.service.IInsuranceService;
import com.oa.admin.service.IMaintainService;
import com.oa.admin.vo.*;
import com.oa.core.PageResult;
import com.oa.admin.entity.Car;
import com.oa.admin.mapper.CarMapper;
import com.oa.admin.service.ICarService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.oa.core.constant.Constant;
import com.oa.core.enumm.CodeEnum;
import com.oa.core.exception.BusinessException;
import com.oa.core.exception.DataIsEmptyException;
import com.oa.core.utils.DateUtil;
import com.oa.core.utils.ExcelUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.plugins.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

import static com.oa.core.utils.Validate.validate;

/**
 * <p>
 * 车俩表 服务实现类
 * </p>
 *
 * @author syb123
 * @since 2019-01-22
 */
@Service
public class CarServiceImpl extends ServiceImpl<CarMapper, Car> implements ICarService {

    private final CarMapper carMapper;
    private final IInsuranceService insuranceService;
    private final MaintainMapper maintainMapper;
    private final CarApplicationMapper carApplicationMapper;
    private final IMaintainService maintainService;
    private final ICarApplicationService carApplicationService;
    @Autowired
    private HttpServletResponse response;


    @Autowired
    public CarServiceImpl(CarMapper carMapper, IInsuranceService insuranceService, MaintainMapper maintainMapper, CarApplicationMapper carApplicationMapper, IMaintainService maintainService, ICarApplicationService carApplicationService) {
        this.carMapper = carMapper;
        this.insuranceService = insuranceService;
        this.maintainMapper = maintainMapper;

        this.carApplicationMapper = carApplicationMapper;
        this.maintainService = maintainService;
        this.carApplicationService = carApplicationService;
    }

    @Override
    @CommonService
    public PageResult<Car> findList(Integer pageNum, Integer pageSize) {
        if (pageNum == null) {
            List<Car> list = carMapper.findList();
            return new PageResult<>(list);
        } else {
            // 当前页，总条数 构造 page 对象
            Page<Car> page = new Page<>(pageNum, pageSize);
            //查询
            List<Car> list = carMapper.findList(page);
            return new PageResult<>(list);

        }
    }

    /**
     * 根据id查询
     */
    @Override
    @CommonService
    public Car findCarById(String id) {
        return carMapper.findById(id);
    }

    /**
     * 新增车辆
     *
     * @param carAddDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp addCar(CarAddDTO carAddDTO) throws BusinessException {

        CheckoutParam(carAddDTO);

        Car car = new Car();

        BeanUtils.copyProperties(carAddDTO, car);

        try {
            carMapper.insert(car);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("添加车辆失败!");
        }

        //保险
        List<InsuranceDTO> insuranceDTOList = carAddDTO.getInsuranceDTOList();
        if (CollUtil.isNotEmpty(insuranceDTOList)) {
            List<Insurance> insuranceList = new ArrayList<>();
            insuranceDTOList.forEach(x -> {
                Insurance insurance = new Insurance();
                BeanUtils.copyProperties(x, insurance);
                insurance.setCarId(car.getId());
                insuranceList.add(insurance);
            });

            try {
                insuranceService.insertBatch(insuranceList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("添加保险信息失败!");
            }
        }
        return new Resp<String>().success("新增车辆成功!");
    }


    /**
     * 参数校验
     *
     * @param
     */
    public void CheckoutParam(CarAddDTO carAddDTO) throws BusinessException {
        if (!StringUtils.isEmpty(carAddDTO)) {
            List<String> validate = validate(carAddDTO);
            if (CollUtil.isNotEmpty(validate)) {
                throw new BusinessException(CodeEnum.PARAMETERS_OF_THE_ABNORMAL.getCode(), validate.toString());
            }
        }
    }

    /**
     * 根据条件查询车辆列表
     *
     * @param carConditionDTO
     * @return
     */
    @Override
    @CommonService
    public PageResult findCarListByCondition(CarConditionDTO carConditionDTO) throws DataIsEmptyException {

        if (StringUtils.isEmpty(carConditionDTO.getPage())) {
            List<CarListVO> carListVOList = carMapper.findCarListByCondition(carConditionDTO);
            if (CollUtil.isEmpty(carListVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<CarListVO>(carListVOList);

        } else {
            Page<CarListVO> page = new Page<>(carConditionDTO.getPage(), carConditionDTO.getLimit());
            List<CarListVO> carListVOList = carMapper.findCarListByCondition(page, carConditionDTO);
            if (CollUtil.isEmpty(carListVOList)) {
                throw new DataIsEmptyException();
            }
            return new PageResult<CarListVO>(carListVOList);
        }

    }

    /**
     * 根据主键id查询车辆详情
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    public Resp findCarDetailsById(String id) {
        CarDetailsVO carDetailsVO = new CarDetailsVO();

        List<InsuranceDetailsVO> insuranceDetailsVOList = new ArrayList<>();

        List<MaintainDetailsVO> maintainDetailsVOList = new ArrayList<>();

        List<CarApplication> carApplicationList = new ArrayList<>();

        Car car = carMapper.findById(id);
        BeanUtils.copyProperties(car, carDetailsVO);//车辆

        //保险
        List<Insurance> insuranceList = insuranceService.selectList(new EntityWrapper<Insurance>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
        if (CollUtil.isNotEmpty(insuranceList)) {
            insuranceList.forEach(x -> {
                InsuranceDetailsVO insuranceDetailsVO = new InsuranceDetailsVO();
                BeanUtils.copyProperties(x, insuranceDetailsVO);
                insuranceDetailsVOList.add(insuranceDetailsVO);
            });
        }

        //维修/保养
        List<Maintain> maintains = maintainMapper.selectList(new EntityWrapper<Maintain>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
        if (CollUtil.isNotEmpty(maintains)) {
            maintains.forEach(x -> {
                MaintainDetailsVO maintainDetailsVO = new MaintainDetailsVO();
                BeanUtils.copyProperties(x, maintainDetailsVO);
                maintainDetailsVOList.add(maintainDetailsVO);
            });
        }

        //用车申请
        List<CarApplication> carApplications = carApplicationMapper.selectList(new EntityWrapper<CarApplication>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
        if (CollUtil.isNotEmpty(carApplications)) {
            carApplications.forEach(x -> {
                carApplicationList.add(x);
            });
        }

        carDetailsVO.setInsuranceDetailsVOList(insuranceDetailsVOList);
        carDetailsVO.setMaintainDetailsVOList(maintainDetailsVOList);
        carDetailsVO.setCarApplicationList(carApplicationList);


        return new Resp<CarDetailsVO>().success(carDetailsVO);
    }

    /**
     * 根据主键id修改车辆详细信息
     *
     * @param carUpdateDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp updateCarDetailsById(CarUpdateDTO carUpdateDTO) throws BusinessException {

        Car car = new Car();
        BeanUtils.copyProperties(carUpdateDTO, car);

        try {
            updateById(car);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("修改车辆信息失败!");
        }

        //保险
        List<Insurance> insuranceList = insuranceService.selectList(new EntityWrapper<Insurance>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
        if (CollUtil.isNotEmpty(insuranceList)) {
            insuranceList.forEach(x -> {
                insuranceService.deleteById(x.getId());
            });
        }

        List<InsuranceDetailsVO> insuranceDetailsVOList = carUpdateDTO.getInsuranceDetailsVOList();
        if (CollUtil.isNotEmpty(insuranceDetailsVOList)) {
            List<Insurance> voList = new ArrayList<>();
            insuranceDetailsVOList.forEach(x -> {
                Insurance insurance = new Insurance();
                BeanUtils.copyProperties(x, insurance);
                insurance.setCarId(car.getId());
                voList.add(insurance);
            });

            try {
                insuranceService.insertBatch(voList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("修改车辆保险信息失败!");
            }
        }

        //维修保养
        List<Maintain> maintains = maintainMapper.selectList(new EntityWrapper<Maintain>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
        if (CollUtil.isNotEmpty(maintains)) {
            maintains.forEach(x -> {
                maintainMapper.deleteById(x.getId());
            });
        }

        List<MaintainDetailsVO> maintainDetailsVOList = carUpdateDTO.getMaintainDetailsVOList();
        if (CollUtil.isNotEmpty(maintainDetailsVOList)) {
            List<Maintain> voList = new ArrayList<>();
            maintainDetailsVOList.forEach(x -> {
                Maintain maintain = new Maintain();
                BeanUtils.copyProperties(x, maintain);
                maintain.setCarId(car.getId());
                voList.add(maintain);
            });

            try {
                maintainService.insertBatch(voList);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("修改车辆维修保养信息失败!");
            }
        }

        //用车申请
//        List<CarApplication> carApplications = carApplicationMapper.selectList(new EntityWrapper<CarApplication>().eq("is_deleted", Constant.IS_DELETE_NO).eq("car_id", car.getId()));
//        if (CollUtil.isNotEmpty(carApplications)) {
//            carApplications.forEach(x -> {
//                carApplicationMapper.deleteById(x.getId());
//            });
//        }

//        List<CarApplication> carApplicationList = carUpdateDTO.getCarApplicationList();
//        if (CollUtil.isNotEmpty(carApplicationList)) {
//            try {
//                carApplicationService.insertBatch(carApplicationList);
//            } catch (Exception e) {
//                e.printStackTrace();
//                throw new BusinessException("修改用车申请信息失败!");
//            }
//        }

        return new Resp<String>().success("修改信息成功!");
    }

    /**
     * 车辆维修/保养
     *
     * @param carMaintatainDTO
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp carMaintain(CarMaintatainDTO carMaintatainDTO) throws BusinessException {

        Maintain maintain = new Maintain();
        BeanUtils.copyProperties(carMaintatainDTO, maintain);

        try {
            maintainMapper.insert(maintain);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("添加车辆维修/保养信息失败!");
        }

        //更改车辆状态
        Car car = carMapper.findById(maintain.getCarId());
        car.setMaintain("1");

        try {
            carMapper.updateById(car);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("更改车辆状态失败!");
        }

        return new Resp<String>().success("添加车辆维修/保养信息成功!");
    }

    /**
     * 修改车辆状态为正常
     *
     * @param id
     * @return
     */
    @Override
    @CommonService
    @Transactional
    public Resp updateCarStatusNormal(String id) throws BusinessException {

        //更改车辆状态为正常
        Car car = carMapper.findById(id);
        car.setMaintain("2");

        try {
            carMapper.updateById(car);
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("更改车辆状态失败!");
        }

        return new Resp<String>().success("更改车辆状态成功!");
    }

    /**
     * 导出车辆列表
     *
     * @return
     */
    @Override
    @CommonService
    public Resp exportCarList() throws DataIsEmptyException, BusinessException {

        List<CarListVO> listVOList = carMapper.findCarListByCondition(null);
        if (CollUtil.isNotEmpty(listVOList)) {
            List<CarExportVO> carExportVOList = new ArrayList<>();
            listVOList.forEach(x -> {
                CarExportVO carExportVO = new CarExportVO();
                BeanUtils.copyProperties(x, carExportVO);
                carExportVOList.add(carExportVO);
            });

            if (CollUtil.isNotEmpty(carExportVOList)) {
                carExportVOList.forEach(x -> {
                    x.setYearCarefulRemind(x.getYearCarefulRemind() + "天");
                });
            }


            String[] rowName = {"状态", "购车时间", "车牌号", "使用部门", "使用人员", "年审时间", "年审提醒"};

            try {
                ExcelUtil.downloadExcel("车辆表" + DateUtil.getDayMonth(), rowName, carExportVOList, "车辆表" + DateUtil.getDayMonth() + ".xls", response);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException("导出车辆excel表格失败!");
            }

            return new Resp<>().success("导出车辆excel表格成功!");
        }


        throw new DataIsEmptyException();
    }
}
